package cn.ciis.server.handler;

import cn.ciis.basic.TioHandlerInterface;
import cn.ciis.basic.kit.ByteKit;
import cn.ciis.basic.kit.CiisKit;
import cn.ciis.basic.model.Equipment;
import cn.ciis.basic.plugin.CiisHandler;
import cn.ciis.basic.plugin.CiisSessionContext;
import cn.ciis.server.CiisPacket;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.Ret;

import java.time.LocalDateTime;
import java.util.Optional;

/**
 * 心跳包处理
 */
@TioHandlerInterface(order = 1)
public class HeartbeatHandler extends CiisHandler {

    @Override
    public void handle(CiisPacket ciisPacket, CiisSessionContext ciisSessionContext) {

        if(StrUtil.equalsIgnoreCase("aa", ByteKit.bytesToHexString(ciisPacket.getType())) &&
                StrUtil.equalsIgnoreCase("5ad2", ByteKit.bytesToHexString(ciisPacket.getCmd()))){//判断是否是心跳包
            LogKit.info("接收到客户端发送过来的信息:{}",ByteKit.bytesToHexString(ciisPacket.getBody()));

            Optional<Equipment> equipment = ciisSessionContext.getEquipment();

            if(equipment.isPresent()){
                Ret ret = analyze(ciisPacket.getBody(), equipment.get());
                equipment.get().put("valve_str", ret.getStr("valve_str"));
                equipment.get().put("sensor_str", ret.getStr("sensor_str"));
            }
            reply(ciisSessionContext,ciisPacket);
        }else{
            goNext(ciisPacket,ciisSessionContext);
        }

    }

    /**
     * 回复客户端信息
     * @param ciisSessionContext
     */
    public void reply(CiisSessionContext ciisSessionContext,CiisPacket ciisPacket){
        LocalDateTime now = LocalDateTime.now();//获取系统当前时间
        StrBuilder msg = StrBuilder.create();

        msg.append(ByteKit.DecToHexString((now.getYear()-2000),1));
        msg.append(ByteKit.DecToHexString(now.getMonthValue(),1));
        msg.append(ByteKit.DecToHexString(now.getDayOfMonth(),1));
        msg.append(ByteKit.DecToHexString(now.getHour(),1));
        msg.append(ByteKit.DecToHexString(now.getMinute(),1));
        msg.append(ByteKit.DecToHexString(now.getSecond(),1));
        msg.append(ByteKit.DecToHexString(now.getDayOfWeek().getValue(), 1));
        ciisPacket.setBody(ByteKit.hexStr2Bytes(msg.toString()));
        boolean sendMsg = CiisKit.sendMsg(ciisSessionContext, ciisPacket);

        if (!sendMsg){
            LogKit.error("回复客户端心跳信息失败！");
        }
    }

    /**
     * 解析阀门数量及传感器数量
     *
     * @param body
     * @return
     */
    public Ret analyze(byte[] body,Equipment equipment){


        byte[] valve_byte = new byte[]{body[0]};//阀门数量

        int valve_num;
        int valve_byte_count;//阀门状态占用字节数
        if(equipment.get("valve_num") != null ){
            valve_num = equipment.getInt("valve_num");
            valve_byte_count = equipment.getInt("valve_byte_count");
        }else{
            valve_num = Integer.parseInt(ByteKit.bytesToHexString(valve_byte), 16);
            valve_byte_count = (int) Math.ceil(valve_num/8.0);
            equipment.put("valve_num", valve_num); //阀门数量
            equipment.put("valve_byte_count", valve_byte_count);//占用字节数量
        }

        byte[] valve_data = new byte[valve_byte_count];//阀门状态byte数据

        for (int i = 0; i<valve_byte_count;i++){
            valve_data[i] = body[i+1];
        }

        byte[][] split = ArrayUtil.split(valve_data, 1);
        StrBuilder builder = StrBuilder.create();
        for (int i = 0; i < split.length;i++){
            builder.append(ByteKit.bytesToBin(split[i]));
        }
        String valve_str =  StrUtil.sub(builder, builder.length()-valve_num, builder.length());
        equipment.setValveStr(valve_str);
        LogKit.debug("阀门数量:{}",valve_num);
        LogKit.debug("解析出来的阀门状态:{}", valve_str);

        int sensor_begin_index = 1+valve_byte_count;
        //传感器数量
        byte[] sensor_byte = new byte[] {
            body[sensor_begin_index]
        };
        int sensor_num = Integer.parseInt(ByteKit.bytesToHexString(sensor_byte),16);

        int sensor_byte_count = (int) Math.ceil(sensor_num/8.0);//传感器状态占用字节数
        byte[] sensor_data = new byte[sensor_byte_count];//传感器状态byte数据

        for (int i = 0; i <sensor_byte_count;i++){
            sensor_data[i] = body[i+1+sensor_begin_index];
        }

        byte[][] split_sensor = ArrayUtil.split(sensor_data, 1);
        StrBuilder builder_sensor = StrBuilder.create();
        for (int i = 0; i < split_sensor.length;i++){
            builder_sensor.append(ByteKit.bytesToBin(split_sensor[i]));
        }

        String sensor_str = builder_sensor.subString(builder_sensor.length()-sensor_num, builder_sensor.length());
        equipment.setSensorStr(sensor_str);
        LogKit.debug("传感器数量:{}",sensor_num);
        LogKit.debug("解析出来的传感器状态:{}",builder_sensor);
        return Ret.ok("sensor_num",sensor_num).set("valve_num", valve_num).set("valve_str", valve_str)
                .set("sensor_str", sensor_str);
    }
}
